﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WriteBugs.Library.Model;

namespace WriteBugs.Controls
{
    /// <summary>
    /// TreeViewAdv.xaml 的交互逻辑
    /// </summary>
    public partial class TreeViewAdv : UserControl
    {
        public TreeViewAdv()
        {
            InitializeComponent();
        }

        #region 依赖属性

        /// <summary>
        /// Root
        /// </summary>
        public TreeViewAdvNodeItem TreeViewAdvNodeItem
        {
            get { return (TreeViewAdvNodeItem)GetValue(TreeViewAdvNodeItemProperty); }
            set { SetValue(TreeViewAdvNodeItemProperty, value); }
        }

        public static readonly DependencyProperty TreeViewAdvNodeItemProperty =
        DependencyProperty.Register("TreeViewAdvNodeItem", typeof(TreeViewAdvNodeItem), typeof(TreeViewAdv), new UIPropertyMetadata(null, TreeViewAdvNodeItemPropertyChanged));

        private static void TreeViewAdvNodeItemPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs arg)
        {
            TreeViewAdv? control = obj as TreeViewAdv;
            TreeViewAdvNodeItem Data = (TreeViewAdvNodeItem)arg.NewValue;
            Data.IsRoot = true;

            if (control != null && Data != null)
            {
                control.treeView.Items.Clear();
                control.treeView.Items.Add(Data);
            }
        }


        public TreeViewAdvNodeItem SelectedItem
        {
            get { return (TreeViewAdvNodeItem)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(TreeViewAdvNodeItem), typeof(TreeViewAdv), new UIPropertyMetadata(null, SelectedItemPropertyChanged));

        private static void SelectedItemPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs arg)
        {

        }
        #endregion

        #region SelectedItemChanged事件
        public static readonly RoutedEvent _SelectedItemChanged
           = EventManager.RegisterRoutedEvent("SelectedItemChanged", RoutingStrategy.Bubble, typeof(TreeViewAdvSelectedItemChangesRoutedEventHandler), typeof(TreeViewAdv));
        public event TreeViewAdvSelectedItemChangesRoutedEventHandler SelectedItemChanged
        {
            add
            {
                AddHandler(_SelectedItemChanged, value);
            }
            remove
            {
                RemoveHandler(_SelectedItemChanged, value);
            }
        }

        private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (this.treeView.SelectedItem != null)
            {
                SelectedItem = e.NewValue as TreeViewAdvNodeItem;

                TreeViewAdvSelectedItemChangesRoutedEventArgs args = new(_SelectedItemChanged, this.treeView)
                {
                    SelectedItem = e.NewValue as TreeViewAdvNodeItem,
                };
                RaiseEvent(args);
            }
        }

        #endregion

        #region StartDrag

        private void treeView_MouseMove(object sender, MouseEventArgs e)
        {
            if (sender is TreeView tree && e.LeftButton == MouseButtonState.Pressed && treeView.SelectedItem != null)
            {
                DragDrop.DoDragDrop(tree, treeView.SelectedItem, DragDropEffects.Move);
            }
        }
        #endregion

        #region Drag       

        public DragInfo DragInfo
        {
            get { return (DragInfo)GetValue(DragInfoProperty); }
            set { SetValue(DragInfoProperty, value); }
        }

        public static readonly DependencyProperty DragInfoProperty =
            DependencyProperty.Register("DragInfo", typeof(DragInfo), typeof(TreeViewAdv), new UIPropertyMetadata(null, null));

        public static readonly RoutedEvent _Dragged
           = EventManager.RegisterRoutedEvent("Dragged", RoutingStrategy.Bubble, typeof(TreeViewAdvDraggedRoutedEventHandler), typeof(TreeViewAdv));
        public event TreeViewAdvDraggedRoutedEventHandler Dragged
        {
            add
            {
                AddHandler(_Dragged, value);
            }
            remove
            {
                RemoveHandler(_Dragged, value);
            }
        }

        private void treeView_DragOver(object sender, DragEventArgs e)
        {
            //自动Expand节点
            Point pos = e.GetPosition(this.treeView);
            HitTestResult HitTestResult = VisualTreeHelper.HitTest(this.treeView, pos);
            if (HitTestResult != null)
            {
                TreeViewItem selectedItem = Utils.FindVisualParent<TreeViewItem>(HitTestResult.VisualHit);
                if (selectedItem != null)
                {
                    selectedItem.IsExpanded = true;
                }
            }

            //判断是否允许拖动          
            e.Effects = DragDropEffects.None;

            if (e.Data.GetData(typeof(ListViewAdvNodeItem)) is ListViewAdvNodeItem fromListNode)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    if (txtTitle.Tag is Excerpt toExcerpt)
                    {
                        if (CanDrop(fromListNode.Excerpt, toExcerpt))
                        {
                            e.Effects = DragDropEffects.Move;
                        }
                    }
                }

                //显示装饰器
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.treeView);
                if (adornerLayer != null)
                {
                    Adorner[] adorners = adornerLayer.GetAdorners(this.treeView);
                    if (adorners != null)
                    {
                        foreach (var adorner in adorners)
                        {
                            adornerLayer.Remove(adorner);
                        }
                    }

                    DragTitleAdorner _adorner = new DragTitleAdorner(this.treeView, pos, fromListNode.Excerpt?.Title);
                    adornerLayer.Add(_adorner);
                }
            }

            if (e.Data.GetData(typeof(TreeViewAdvNodeItem)) is TreeViewAdvNodeItem fromTreeNode)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    if (txtTitle.Tag is Excerpt toExcerpt)
                    {
                        if (CanDrop(fromTreeNode.Excerpt, toExcerpt))
                        {
                            e.Effects = DragDropEffects.Move;
                        }
                    }
                }

                //显示装饰器
                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.treeView);
                if (adornerLayer != null)
                {
                    Adorner[] adorners = adornerLayer.GetAdorners(this.treeView);
                    if (adorners != null)
                    {
                        foreach (var adorner in adorners)
                        {
                            adornerLayer.Remove(adorner);
                        }
                    }

                    DragTitleAdorner _adorner = new DragTitleAdorner(this.treeView, pos, fromTreeNode.Excerpt?.Title);
                    adornerLayer.Add(_adorner);
                }
            }

            e.Handled = true;
        }

        private static bool CanDrop(Excerpt? fromExcerpt, Excerpt? toExcerpt)
        {
            if (fromExcerpt == toExcerpt || fromExcerpt?.Parent == toExcerpt)
            {
                return false;
            }

            while (true)
            {
                if (toExcerpt?.Parent == null)
                {
                    break;
                }

                if (toExcerpt.Parent == fromExcerpt)
                {
                    return false;
                }

                toExcerpt = toExcerpt?.Parent;
            }

            return true;
        }

        private void treeView_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetData(typeof(ListViewAdvNodeItem)) is ListViewAdvNodeItem
                || e.Data.GetData(typeof(TreeViewAdvNodeItem)) is TreeViewAdvNodeItem)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    txtTitle.FontWeight = FontWeights.Bold;
                }
            }
        }

        private void treeView_DragLeave(object sender, DragEventArgs e)
        {
            if (e.Data.GetData(typeof(ListViewAdvNodeItem)) is ListViewAdvNodeItem
                || e.Data.GetData(typeof(TreeViewAdvNodeItem)) is TreeViewAdvNodeItem)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    txtTitle.FontWeight = FontWeights.Normal;
                }

                CloseAdorners();
            }
        }

        private void treeView_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetData(typeof(ListViewAdvNodeItem)) is ListViewAdvNodeItem fromListNode)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    txtTitle.FontWeight = FontWeights.Normal;

                    if (txtTitle.Tag is Excerpt toExcerpt)
                    {
                        DragInfo = new DragInfo
                        {
                            SourceExcerpt = fromListNode?.Excerpt,
                            TargetExcerpt = toExcerpt,
                        };

                        TreeViewAdvDraggedRoutedEventArgs args = new(_Dragged, this.treeView)
                        {
                            DragInfo = DragInfo,
                        };
                        RaiseEvent(args);

                        CloseAdorners();
                    }
                }
            }

            if (e.Data.GetData(typeof(TreeViewAdvNodeItem)) is TreeViewAdvNodeItem fromTreeNode)
            {
                if (e.OriginalSource is TextBlock txtTitle)
                {
                    txtTitle.FontWeight = FontWeights.Normal;

                    if (txtTitle.Tag is Excerpt toExcerpt)
                    {
                        DragInfo = new DragInfo
                        {
                            SourceExcerpt = fromTreeNode?.Excerpt,
                            TargetExcerpt = toExcerpt,
                        };

                        TreeViewAdvDraggedRoutedEventArgs args = new(_Dragged, this.treeView)
                        {
                            DragInfo = DragInfo,
                        };
                        RaiseEvent(args);

                        CloseAdorners();
                    }
                }
            }
        }


        private void CloseAdorners()
        {
            //关闭装饰器
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.treeView);
            if (adornerLayer != null)
            {
                Adorner[] adorners = adornerLayer.GetAdorners(this.treeView);
                if (adorners != null)
                {
                    foreach (var adorner in adorners)
                    {
                        adornerLayer.Remove(adorner);
                    }
                }
            }
        }

        #endregion
    }
}
